package jp.sourceforge.akjrcp.ui;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;

import jp.sourceforge.akjrcp.akj_betas.Messages;
import jp.sourceforge.akjrcp.commons.util.FileNameUtils;
import jp.sourceforge.akjrcp.util.WildCard;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;


/**
 *moved use commons
 * @author aki
 *@deprecated
 */
public class EditableFileList extends TableViewer{
	public static Log log=LogFactory.getLog(EditableFileList.class);
	protected ArrayList<File> fileList=new ArrayList<File>();
	private MenuItem moveTop;
	private MenuItem moveBottom;
	private MenuItem moveUp;
	private MenuItem moveDown;
	private MenuItem removeFile;
	private List<IPropertyChangeListener> propertyChangeListeners=new ArrayList<IPropertyChangeListener>();
	
	public void addPropertyChangeListener(IPropertyChangeListener listener){
		propertyChangeListeners.add(listener);
	}
	public void removePropertyChangeListener(IPropertyChangeListener listener){
		propertyChangeListeners.remove(listener);
	}
	
	private String filterExtension;
	private boolean allowDoplicate=false;
	public class MenuSelection implements SelectionListener{

		public void widgetSelected(SelectionEvent e) {
			if(e.getSource()==addfile){
				openFile();
			}else if(e.getSource()==moveTop){
				moveTop();
				}else if(e.getSource()==moveBottom){
				moveBottom();
				}else if(e.getSource()==moveUp){
				moveUp();
				}else if(e.getSource()==moveDown){
				moveDown();
				}else if(e.getSource()==removeFile){
				removeFile();
				}
			//getControl().redraw();
			refresh(true);
		}

		public void widgetDefaultSelected(SelectionEvent e) {
			// TODO Auto-generated method stub
			
		}
		
	}
	public void removeFile(){
		 log.info("remove");
	
			File files[]=getSelectionFiles();
			for (int i = 0; i < files.length; i++) {
				fileList.remove(files[i]);
			}
			if(files.length>0){
				firePropertyChanged(ACTION_REMOVE);
			}
			
	}
	public void moveUp(){
		File files[]=getSelectionFiles();
		
		if(files.length==1){
			int index=fileList.indexOf(files[0]);
			fileList.remove(files[0]);
			fileList.add(Math.max(0,index-1),files[0]);
			firePropertyChanged(ACTION_MOVE);
		}
	}
	
	public void moveDown(){
		File files[]=getSelectionFiles();
		if(files.length==1){
			int index=fileList.indexOf(files[0]);
			fileList.remove(files[0]);
			fileList.add(Math.min(fileList.size(),index+1),files[0]);
			firePropertyChanged(ACTION_MOVE);
		}
	}
	
	public void moveTop(){
		File files[]=getSelectionFiles();
		if(files.length==1){
			fileList.remove(files[0]);
			fileList.add(0,files[0]);
			firePropertyChanged(ACTION_MOVE);
		}
	}
	
	public void moveBottom(){
		File files[]=getSelectionFiles();
		if(files.length==1){
			fileList.remove(files[0]);
			fileList.add(files[0]);
			firePropertyChanged(ACTION_MOVE);
		}
	}
	/**
	 * must call setInput
	 * @param parent
	 * @param style
	 */
	public EditableFileList(Composite parent,int style){
		super(parent,style);
		this.setLabelProvider(new ViewLabelProvider());
		this.setContentProvider(new ViewContentProvider());
		
		MenuSelection selection=new MenuSelection();
		popUpMenu = new Menu(getTable());
			getTable().setMenu(popUpMenu);
	        addfile = new MenuItem(popUpMenu, SWT.PUSH);
			addfile.setText(Messages.getString("FileListTable.addfile")); //$NON-NLS-1$
	        addfile.addSelectionListener(selection);
	        
	        MenuItem s1=new MenuItem(popUpMenu,SWT.SEPARATOR);
	        moveTop = new MenuItem(popUpMenu, SWT.PUSH);
	        moveTop.setText(Messages.getString("FileListTable.moveTop")); //$NON-NLS-1$
	        moveTop.addSelectionListener(selection);
	        
	        moveBottom = new MenuItem(popUpMenu, SWT.PUSH);
	        moveBottom.setText(Messages.getString("FileListTable.moveBottom")); //$NON-NLS-1$
	        moveBottom.addSelectionListener(selection);
	        
	        moveUp = new MenuItem(popUpMenu, SWT.PUSH);
	        moveUp.setText(Messages.getString("FileListTable.moveUp")); //$NON-NLS-1$
	        moveUp.addSelectionListener(selection);
	        
	        moveDown = new MenuItem(popUpMenu, SWT.PUSH);
	        moveDown.setText(Messages.getString("FileListTable.moveDown")); //$NON-NLS-1$
	        moveDown.addSelectionListener(selection);
	        MenuItem s2=new MenuItem(popUpMenu,SWT.SEPARATOR);
	        
	        removeFile = new MenuItem(popUpMenu, SWT.PUSH);
	        removeFile.setText(Messages.getString("FileListTable.removeFile")); //$NON-NLS-1$
	        removeFile.addSelectionListener(selection);
	        
	        getTable().addKeyListener(new KeyAdapter(){
	        	 public void keyReleased(KeyEvent event) {
	        		
	        	        if(event.keyCode==127){ //DELETE KEY
	        	            removeFile();
	        	            refresh(true);
	        	        }
	        	       
	        	    }
	        });
	        

	        Transfer[] types = new Transfer[] {FileTransfer.getInstance()};
	    	
	    	int operations = DND.DROP_MOVE | DND.DROP_COPY ;
	    	
	    	
	    		
	    	
	    	
	    	
	    	
	    		DropTarget target2 = new DropTarget (getTable(), operations);
	    		target2.setTransfer(types);
	    	
	    		target2.addDropListener(new DropMonitor());
	    		
	    		
	    		
	    		this.getTable().setLinesVisible(true);
	        
	    		
	}
	
	  public class DropMonitor extends DropTargetAdapter{
			public void dragEnter(DropTargetEvent event){
				//log.infodrag enter:"+event.data);
			}
			public void dragOver(DropTargetEvent event){
				//log.infodrag over:"+event.data);
				}
			public void drop(DropTargetEvent event){
				//log.infodrop:"+event.data);
				
				//log.info(event.data.getClass().getName());
				String files[]=(String[])event.data;
			
			
				for(int i=0;i<files.length;i++){
					addFilePath(files[i]);
				}
				
				}
		}
	  
	  /**
	   * @deprecated
	   * use addFile;
	   */
	  public void add(Object object){
		  super.add(object);
	  }
	  public void addFile(File file){
	       
	        if(filenameFilter!=null){
	        	if(filenameFilter.accept(file.getParentFile(),file.getName())){
	        		innerAddFile(file);
	        	}
	        }else{
	        	innerAddFile(file);
	        }
	    }
	  
	  public void addFilePath(String path){
		  addFile(new File(path));
	    }
	  
	public EditableFileList(Composite parent) {
		super(parent);
		
		this.setLabelProvider(new ViewLabelProvider());
		this.setContentProvider(new ViewContentProvider());
		
	}
	
	protected FilenameFilter filenameFilter;
	private MenuItem addfile;
	

	public void openFile(){
		FileDialog dialog=new FileDialog(this.getTable().getShell(),SWT.OPEN|SWT.MULTI);
		dialog.setFilterExtensions(new String[]{filterExtension});//TODO support multi
		String path=dialog.open();
		if(path!=null){
			String names[]=dialog.getFileNames();
			for (int i = 0; i < names.length; i++) {
				
				addFilePath(names[i]);
			}
		}
	}

	
	
            class ViewContentProvider implements IStructuredContentProvider {
        		public void inputChanged(Viewer v, Object oldInput, Object newInput) {
        			
        		}
        		public void dispose() {
        		}
        		public Object[] getElements(Object parent) {
        			
        			return fileList.toArray();
        		}
        	}
            
        	class ViewLabelProvider extends LabelProvider implements ITableLabelProvider {
        		public String getColumnText(Object obj, int index) {
        			
        			return FileNameUtils.shortenFileName(((File)obj).getAbsolutePath());
        		}
        		public Image getColumnImage(Object obj, int index) {
        			return null;
        		}

        	}
	
	
	





	protected void innerAddFile(File file){
		if(!allowDoplicate){
		synchronized(this){
		File files[]=getFileList();
		for (int i = 0; i < files.length; i++) {
			if(files[i].getAbsolutePath().equals(file.getAbsolutePath())){
				log.info("duplicate not allowed");
				return;
			}
			}
		}
		}
		fileList.add(file);
		firePropertyChanged(ACTION_ADD);
		//fro d&d
		refresh(true);
	}
	
	public static final String ACTION_ADD="add";
	public static final String ACTION_REMOVE="remove";
	public static final String ACTION_MOVE="move";
	private Menu popUpMenu;
	public void firePropertyChanged(String type){
		PropertyChangeEvent event=new PropertyChangeEvent(this,type,null,null);
		IPropertyChangeListener listenres[]=propertyChangeListeners.toArray(new IPropertyChangeListener[propertyChangeListeners.size()]);
		for (int i = 0; i < listenres.length; i++) {
			listenres[i].propertyChange(event);
		}
	}


	public FilenameFilter getFilenameFilter() {
		return filenameFilter;
	}
	
	public void setFilenameFilter(FilenameFilter filenameFilter) {
		this.filenameFilter = filenameFilter;
	}
	public File[] getFileList() {
		return (File[])fileList.toArray(new File[0]);
	}
	
	public int countFiles(){
		return fileList.size();
	}
	
	
	public File[] getSelectionFiles() {
		ISelection selection=this.getSelection();
		return (File[]) ((IStructuredSelection)selection).toList().toArray(new File[0]);
	}
	public void setLayoutData(GridData layoutData) {
		getTable().setLayoutData(layoutData);
	}
	public String getFilterExtension() {
		return filterExtension;
	}
	public void setFilterExtension(String filterExtension) {
		this.filterExtension = filterExtension;
		if(filterExtension!=null){
			setFilenameFilter(new ExtensionFilenameFilter(filterExtension));
		}
	}
	
	public static class ExtensionFilenameFilter implements FilenameFilter{
		private WildCard wildcards[];
		public ExtensionFilenameFilter(String extensions){
			if(extensions.indexOf(",")!=-1){
				log.warn("now , not supported");
			}
			wildcards=WildCard.parseExtensions(extensions);
			for (int i = 0; i < wildcards.length; i++) {
				//log.trace(wildcards[i].getPattern());
			}
		}
		public boolean accept(File dir, String name) {
			for (int i = 0; i < wildcards.length; i++) {
				if(wildcards[i].match(name)){
					return true;
				}else{
					log.trace(wildcards[i].getPattern()+":not much "+name);
				}
			}
			log.info(":not much any pattern "+name);
			return false;
		}
	}
	public boolean isAllowDoplicate() {
		return allowDoplicate;
	}
	public void setAllowDoplicate(boolean allowDoplicate) {
		this.allowDoplicate = allowDoplicate;
	}
	public Menu getPopUpMenu() {
		return popUpMenu;
	}
	public void setPopUpMenu(Menu popUpMenu) {
		this.popUpMenu = popUpMenu;
	}
}
